// Copyright (c) 2024 Tencent. All rights reserved.
// Author: borryzhang
/*
 * Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
 * for details. All rights reserved. Use of this source code is governed by a
 * BSD-style license that can be found in the LICENSE file.
 */

#include "dart_api_dl.h" /* NOLINT */

#include <stdio.h>
#include <string.h>

#define LITEAV_DART_API_DL_DEFINITIONS(name, R, A) name##_Type name##_DL = NULL;

LITEAV_DART_API_ALL_DL_SYMBOLS(LITEAV_DART_API_DL_DEFINITIONS)

#undef LITEAV_DART_API_DL_DEFINITIONS

typedef void* LiteavDartApiEntry_function;

LiteavDartApiEntry_function LiteavFindFunctionPointer(const LiteavDartApiEntry* entries,
                                                      const char* name) {
    while (entries->name != NULL) {
        if (strcmp(entries->name, name) == 0)
            return entries->function;
        entries++;
    }
    return NULL;
}

intptr_t Liteav_Dart_InitializeApiDL(void* data) {
    LiteavDartApi* dart_api_data = (LiteavDartApi*)data;

    if (dart_api_data->major != LITEAV_DART_API_DL_MAJOR_VERSION) {
        // If the DartVM we're running on does not have the same version as this
        // file was compiled against, refuse to initialize. The symbols are not
        // compatible.
        return -1;
    }
    // Minor versions are allowed to be different.
    // If the DartVM has a higher minor version, it will provide more symbols
    // than we initialize here.
    // If the DartVM has a lower minor version, it will not provide all symbols.
    // In that case, we leave the missing symbols un-initialized. Those symbols
    // should not be used by the Dart and native code. The client is responsible
    // for checking the minor version number himself based on which symbols it
    // is using.
    // (If we would error out on this case, recompiling native code against a
    // newer SDK would break all uses on older SDKs, which is too strict.)

    const LiteavDartApiEntry* dart_api_function_pointers = dart_api_data->functions;

#define LITEAV_DART_API_DL_INIT(name, R, A) \
  name##_DL = (name##_Type)(LiteavFindFunctionPointer(dart_api_function_pointers, #name));
    LITEAV_DART_API_ALL_DL_SYMBOLS(LITEAV_DART_API_DL_INIT)
#undef LITEAV_DART_API_DL_INIT

    return 0;
}
